﻿using System;
using System.Linq;
using STX.Domain;
using STX.Repository;
using STX.Lib.Security;
using STX.Service.Valid.TabAdministratorValid;

namespace STX.Service
{
    public class TabAdministratorService : BaseService<STX.Domain.TabAdministrator>
    {

        public TabBlackListService TabBlackListService { get; set; }
        public Add AddValid { get; set; }
        public Edit EditValid { get; set; }

        #region override base's method

        public override long Add(TabAdministrator entity,
            Action<ITransactionContext, TabAdministrator> successAction = null)
        {
            Valid(entity, AddValid);
            entity.Password =
                HashEncrypt.MD5(string.Format("{0}~!d(ldn:><adDS4&^%{1}", entity.UserName, entity.Password));
            return base.Add(entity);
        }

        public override bool Update(TabAdministrator entity)
        {

            if (entity.Password != "******" && entity.Password.Length < 30)
            {
                Valid(entity, EditValid);
                entity.Password =
                    HashEncrypt.MD5(string.Format("{0}~!d(ldn:><adDS4&^%{1}", entity.UserName, entity.Password));
            }
            Transaction.Commit();
            return Transaction.AffectedRows > 0;
        }

        #endregion

        /// <summary>
        /// 获取此用户
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        private TabAdministrator GetAdministratorByUsername(string username)
        {
            var repository = Transaction.GetRepository<TabAdministrator>();
            var model =
                repository.FindAll()
                    .FirstOrDefault(o=>o.UserName==username);
            return model;
        }

        /// <summary>
        /// 检查该用户是否可以登录
        /// </summary>
        /// <param name="username"></param>
        /// <param name="fun"></param>
        /// <returns></returns>
        public bool CheckLoginUserError(string username, Action<string> fun)
        {
            var user = GetAdministratorByUsername(username);
            if (user == null)
            {
                fun("用户名密码错误");
                return false;
            }
            if (user.IsDisabled)
            {
                fun("用户已被屏蔽");
                return false;
            }
            if (user.ErrorCount > 6)
            {
                fun("你错误登录的次数太多，已被加入黑名单");
                return false;
            }
            if (user.ErrorCount >= 3)
            {
                var ts = (DateTime.Now - user.LastErrorDateTime);
                if (ts.Minutes < 10)
                {
                    fun("你登录的错误次数超过3次，过10分钟再来吧(还有" + (10 - ts.Minutes) + "分钟)");
                    return false;
                }
                return true;
            }
            return true;
        }

        /// <summary>
        /// 使用用户名登录
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool Login(string username, string password, Action<TabAdministrator> fun = null)
        {
            var repository = Transaction.GetRepository<TabAdministrator>();
            var model = repository.FindAll()
                .FirstOrDefault(o=>o.UserName==username);
            if (model == null)
                return false;

            var encryptPassword = HashEncrypt.MD5(string.Format("{0}~!d(ldn:><adDS4&^%{1}", username, password));
            var query = (from s in repository.FindAll()
                where (s.UserName == username && s.Password == encryptPassword)
                select s
                )
                .FirstOrDefault();

            if (query == null)
            {
                model.ErrorCount++;
                model.LastErrorDateTime = DateTime.Now;
                Update(model);
                if (model.ErrorCount > 6)
                {
                    TabBlackListService.AddCurrentToBlackList(TabBlackList.BlockScope.Admin, 30);
                }
                return false;
            }

            if (query.IsDisabled)
                return false;

            if (fun != null)
                fun(query);

            return true;
        }

        public void Login(dynamic options)
        {
            dynamic defaultOptions = new
            {
                Username="",
                Password="",
                onError = new Action<string>(o => { }),
                onSuccess = new Action<string>(o => { }),
            };

            this.Extend(ref defaultOptions, options);

            var isLogin = Login(defaultOptions.Username, defaultOptions.Password);
            if (isLogin)
            {
                defaultOptions.onSuccess();
            }
        }

        public void Extend(ref dynamic op1, dynamic op2)
        {
            
        }

        public void LoginNow()
        {
            var UserName = "苍老师";
            var Password = "123456";

            Login(new
            {
                UserName = UserName,
                Password = Password,
                onSuccess = new Action<string>(o =>
                {
                    //Log(o);
                    //跳转...
                })
            });
        }

        /// <summary>
        /// 使用令牌登录（用于会话超时）
        /// </summary>
        /// <param name="username"></param>
        /// <param name="token"></param>
        /// <param name="fun"></param>
        /// <returns></returns>
        public bool LoginByToken(string username, string token, Action<TabAdministrator> fun = null)
        {
            var query = (from s in FindAll()
                        where (s.UserName == username && s.Token == token)
                        select s
                        ).FirstOrDefault();

            if (query == null || query.IsDisabled) 
                return false;

            if (fun != null) 
                fun(query);

            return true;
        }
    }
}
